// include header files
var crypto = require('crypto');
var message = require('../lib/message');
var database = require('../lib/database');
var fotoString = require('../lib/fotostring');
var fotoNumber = require('../lib/fotonumber');
var fotoImage = require('../lib/fotoimage');
var codeOperation = require('../lib/code');
var fs = require('fs');
var util = require('util');
// connect db
database.connectDataBase();

// api signup
exports.signUp = function(request, response) {
	try {
		var result, code;
		
		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({"code" : code, "result": result} );
			database.closeDatabase();
			return;
		}
		
		var param = JSON.parse(request.param(fotoString.PARAM));

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databasError, collection) {
			if (databasError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}

			if (!param.email || !param.fullName || !param.password) {
				code = codeOperation.PARAMETER_ERROR;
				if (!param.fullName) {
					result = fotoString.FULL_NAME_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				}else if (!param.email) {
					result = fotoString.EMAIL + message.MESSAGE_FIELD_NULL_ERROR;
				}else if (!param.password) {
					result = fotoString.PASSWORD + message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}
			collection.findOne(
					{email : param.email}, 
					{email : fotoString.TRUE, _id : fotoString.FALSE }
			, function(findObjectError, cursor) {
				if (cursor) {
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_EMAIL_EXIST_ERROR;
					response.json({"code" : code, "result": result} );
					database.closeDatabase();
					return;
				} else {
					param.friends = fotoString.EMPTY_STRING;	
					param.dx = fotoString.EMPTY_STRING;
					param.dy = fotoString.EMPTY_STRING;
					param.location = fotoString.EMPTY_STRING;
					param.timeRequest = new Date();
					param.tokenKey = crypto.createHash(fotoString.MD5).update(
							new Date().getTime().toString()).digest(fotoString.HEX);
					collection.insert(param, {
						safe : true
					}, function(insertObjectError, insertObjectResult) {
						if (!insertObjectError) {
							code = codeOperation.OPERATION_SUCCESS;
							
							collection.findOne(
								{email : param.email}, 
								{tokenKey : fotoString.TRUE, _id : fotoString.FALSE, fullName : fotoString.TRUE}, 
							function(findObjectError, findObjectResult ) {
									if (findObjectResult) {
										var result = {tokenKey : findObjectResult.tokenKey, fullName : findObjectResult.fullName};
										response.json({"code" : code, "result": result} );
										database.closeDatabase();
										return;
									}
							});
						}
					});
				}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({"code" : code, "result": result} );
		database.closeDatabase();
		return;
	}
}

// api upload avatar
exports.uploadAvatar = function(request, response) {
	try {
		var result, code;

		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({"code" : code, "result": result} );
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotoString.PARAM));
		
		if (!param.tokenKey) {
			code = codeOperation.PARAMETER_ERROR;
			result = fotoString.TOKEN_KEY_MESSAGE +  message.MESSAGE_FIELD_NULL_ERROR;
			response.json({"code" : code, "result": result} );
			database.closeDatabase();
			return;
		}

		if(!request.files.avatar.name){
			code = codeOperation.PARAMETER_ERROR;
			result = message.MESSAGE_FILE_HAS_ERROR;
			response.json({"code" : code, "result": result} );
			database.closeDatabase();
			return;
		}
		
		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, collection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}
						
			collection.findOne(
					{tokenKey : param.tokenKey} , 
					{tokenKey : fotoString.TRUE , _id : fotoString.FALSE, avatar : fotoString.TRUE} 
			, function(error, findObjectResult){
				if(findObjectResult){
					var savePath = fotoImage.uploadImage(request.files.avatar, findObjectResult._id, fotoNumber.AVATAR);
					collection.update({
						tokenKey : param.tokenKey
					}, {
						$set : {
							avatar: savePath
						}
					}, function(updateObjectError, updateObjectResult){
						if(!updateObjectError){
							code = codeOperation.OPERATION_SUCCESS;
							result = savePath;
						}else{
							code = codeOperation.OPERATION_ERROR;
							result = message.MESSAGE_UNEXPECTED_ERROR;
						}
						response.json({"code" : code, "result": result} );
						database.closeDatabase();
						return;
					});
					
				}else{
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UNEXPECTED_ERROR;
					response.json({"code" : code, "result": result} );
					database.closeDatabase();
					return;
				}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({"code" : code, "result": result} );
		database.closeDatabase();
		return;
	}
}

// api login
exports.login = function(request, response) {
	try {
		if (!request.param(fotoString.PARAM)) {
			code =  codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({"code" : code, "result": result} );
			database.closeDatabase();
			return;
		}

		var result, code;
		var param = JSON.parse(request.param(fotoString.PARAM));

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, collection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}

			if (!param.email || !param.password) {
				code = codeOperation.PARAMETER_ERROR;
				if (!param.email) {
					result = fotoString.EMAIL + message.MESSAGE_FIELD_NULL_ERROR;

				}else if (!param.password) {
					result = fotoString.PASSWORD + message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}
			collection.findOne(
					{email : param.email, password : param.password}, 
					{email : fotoString.TRUE , _id : fotoString.FALSE} ,
					function(findObjectError, findObjectResult) {
						
					if (!findObjectResult) {
						code = codeOperation.OPERATION_ERROR;
						result = message.MESSAGE_LOGIN_FAILED_ERROR;
						response.json({"code" : code, "result": result} );
						database.closeDatabase();
						return;
					} else {
						var tokenKey = crypto.createHash(fotoString.MD5).update(
								new Date().getTime().toString()).digest(fotoString.HEX);
						collection.update({
							"email" : param.email,
							"password" : param.password
						}, {
							$set : {
								"tokenKey" : tokenKey
							}
						}, function(updateObjectError, updateObjectResult) {
							if (!updateObjectError) {
								code = codeOperation.OPERATION_SUCCESS;
								collection.findOne(
										{email : param.email, password : param.password},
										{tokenKey : fotoString.TRUE, _id : fotoString.FALSE, fullName : fotoString.TRUE, avatar : fotoString.TRUE}
								, function(loginError, loginResult) {
									if (!loginError) {
										var result = {
														 "tokenKey" : loginResult.tokenKey,
													     "fullName" : loginResult.fullName,
													     "avatar" : loginResult.avatar
													  };
										
										response.json({"code" : code, "result": result} );
										database.closeDatabase();
										return;
									}
								});
							}
						});
					}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({"code" : code, "result": result} );
		database.closeDatabase();
		return;
	}
}
// api get avatar
exports.getAvatar = function(request, response) {
	try {
		if (!request.param(fotoString.PARAM)) {
			code =  codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({"code" : code, "result": result} );
			database.closeDatabase();
			return;
		}

		var result, code;
		var param = JSON.parse(request.param(fotoString.PARAM));

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, fotoAccountCollection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}
			
			if(!param.tokenKey){
				code = codeOperation.PARAMETER_ERROR;
				result = fotoString.TOKEN_KEY_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}
			
			fotoAccountCollection.findOne({tokenKey : param.tokenKey}, {avatar : fotoString.TRUE, _id : fotoString.TRUE},
					function(findError, findAccountResult){
				if(findAccountResult){
					var avatarPath = findAccountResult.avatar;
					var linkAvatar = fotoString.EMPTY_STRING;	
					var tempPath = findAccountResult.avatar.replace(fotoString.AVATAR_PATH, fotoString.TEMP_PATH);
					if(avatarPath){
						linkAvatar = fotoImage.copyImageToTemp(findAccountResult._id, avatarPath);
						code = codeOperation.OPERATION_SUCCESS;
						result = {"linkAvatar" : linkAvatar};
					}else{
						code = codeOperation.OPERATION_ERROR;
					}
					response.json({"code" : code, "result" : result});
					database.closeDatabase();
					
					
					if(code == codeOperation.OPERATION_SUCCESS){
						var myIntervalId = setInterval(function() {
							fotoImage.deleteImage(tempPath);
							if(myIntervalId){
								clearInterval(myIntervalId);
							}
						}, 60 * 60 * 1000);
					}
					return;
				}else{
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UNEXPECTED_ERROR;
					response.json({"code" : code, "result" : result});
					database.closeDatabase();
					return;
				}			
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({"code" : code, "result": result} );
		database.closeDatabase();
		return;
	}
}
	

// api logout
exports.logout = function(request, response) {
	try {
		var result, code;
		
		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({"code" : code, "result": result} );
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotoString.PARAM));

		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, collection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}

			if (!param.tokenKey) {
				code = codeOperation.PARAMETER_ERROR;
				result = fotoString.TOKEN_KEY_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}
			collection.findOne({
				tokenKey : param.tokenKey	},{tokenKey : fotoString.TRUE, _id :  fotoString.FALSE}, 
				function(findObjectError, findObjectResult) {
					if (!findObjectResult) {
						code = codeOperation.OPERATION_ERROR;
						result = message.MESSAGE_UNEXPECTED_ERROR;
						response.json({"code" : code, "result": result} );
						database.closeDatabase();
						return;
					} else {
						collection.update({
							tokenKey: param.tokenKey
						}, {
							$set : {
								tokenKey : fotoString.EMPTY_STRING
							}
						}, function(updateObjectError, updateObjectResult) {
							if (!updateObjectError) {
								code = codeOperation.OPERATION_SUCCESS;
								result = fotoString.EMPTY_STRING;
								response.json({"code" : code, "result": result} );
								database.closeDatabase();
								return;
							}
						});
					}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({"code" : code, "result": result} );
		database.closeDatabase();
		return;
	}
}

// api update profile
exports.updateProfile = function(request, response) {
	try {
		var result, code;
		
		if (!request.param(fotoString.PARAM)) {
			code = codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.json({"code" : code, "result": result} );
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotoString.PARAM));
		var currentEmail = fotoString.EMPTY_STRING;
		
		fotolaDatabase.collection(fotoString.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(databaseError, collection) {
			if (databaseError) {
				code = codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}

			if (!param.tokenKey || !param.email || !param.fullName
					|| !param.password) {
				code = codeOperation.PARAMETER_ERROR;
				if (!param.fullName) {
					result = fotoString.FULL_NAME_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				}else if (!param.email) {
					result = fotoString.EMAIL + message.MESSAGE_FIELD_NULL_ERROR;
				} else if (!param.password) {
					result =fotoString.PASSWORD +  message.MESSAGE_FIELD_NULL_ERROR;
				}else if (!param.tokenKey) {
					result = fotoString.TOKEN_KEY_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.json({"code" : code, "result": result} );
				database.closeDatabase();
				return;
			}

			collection.findOne({tokenKey : param.tokenKey }, {email : fotoString.TRUE, _id : fotoString.FALSE } ,
					function(findObjectError, findObjectResult) {
				if (!findObjectResult) {
					code = codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UNEXPECTED_ERROR;
					response.json({"code" : code, "result": result} );
					database.closeDatabase();
					return;
				} else {
					currentEmail = findObjectResult.email;
					collection.findOne({
						email : param.email
					}, function(findObjectError, cursor) {
						if (cursor && cursor.email != currentEmail) {
							code = codeOperation.OPERATION_ERROR;
							result = message.MESSAGE_EMAIL_EXIST_ERROR;
							response.json({"code" : code, "result": result} );
							database.closeDatabase();
							return;
						} else {
							collection.update({
								tokenKey : param.tokenKey
							}, {
								$set : {
									email : param.email,
									password : param.password,
									fullName : param.fullName
								}
							}, function(updateObjectError, updateObjectResult) {
								if (!updateObjectError) {
									code = codeOperation.OPERATION_SUCCESS;
									result = fotoString.EMPTY_STRING;
									response.json({"code" : code, "result": result} );
									database.closeDatabase();
									return;
								}
							});
						}
					});
				}
			});
		});
	} catch (unexpectedError) {
		code = codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.json({"code" : code, "result": result} );
		database.closeDatabase();
		return;
	}
}
